package com.franklions.casdoor.example.controller;

import com.franklions.casdoor.example.config.AppConfigProperties;
import com.franklions.casdoor.example.constant.AppConstants;
import com.franklions.casdoor.example.domain.dto.LoginRequest;
import com.franklions.casdoor.example.service.JwtTokenProvider;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * @author flsh
 * @version 1.0
 * @date 2024/6/25
 * @since Jdk 1.8
 */
@Slf4j
@RestController
@RequestMapping("/auth")
public class AuthController {

    @Autowired
    private AppConfigProperties properties;

    private PathMatcher pathMatcher = new AntPathMatcher();

    @PostMapping("/login")
    public ResponseEntity login(@RequestBody LoginRequest request){
        String token = JwtTokenProvider.generateToken(request.getUsername(), AppConstants.TOKEN_SECRET_KEY);
        return ResponseEntity.ok(token);
    }

    /**
     * {
     *     "x-request-id": "b3234ae817d484738b2a668ca470a2ec",
     *     "x-real-ip": "60.25.153.100",
     *     "x-original-method": "GET",
     *     "x-sent-from": "nginx-ingress-controller",
     *     "x-original-url": "http://websitetest.lianwukeji.com/api/actuator/health",
     *     "x-auth-request-redirect": "/api/actuator/health",
     *     "x-original-uri": "/api/actuator/health",
     *     "x-scheme": "http"
     * }
     * @param token
     * @param requestUri
     * @return
     */
    @PostMapping("/verify")
    public ResponseEntity verify(@RequestHeader(value = "x-saas-token",required = false) String token,
                                 @RequestHeader(value = "x-original-uri",required = false) String requestUri,
                                 @RequestHeader(value = "x-original-method",required = false)String requestMethod){

        if("OPTIONS".equalsIgnoreCase(requestMethod)){
            ResponseEntity response = new ResponseEntity<>(HttpStatus.OK);
            return response;
        }


        if(matchesIgnoredPatterns(requestUri)){
            log.info("ignored url,"+requestUri);
            ResponseEntity response = new ResponseEntity<>(HttpStatus.OK);
            return response;
        }

        if(StringUtils.isBlank(token)){
            HttpHeaders headers = new HttpHeaders();
            headers.set("x-saas-errorcode", "401001");
            headers.set("x-saas-errormessage", "User unauthorized.");
            Map<String,String> body = new HashMap<>();
            body.put("errorCode","401001");
            body.put("errorMessage","User unauthorized.");
            ResponseEntity response = new ResponseEntity<>(body,headers,HttpStatus.UNAUTHORIZED);
            return response;
        }
        boolean result = JwtTokenProvider.verifyToken(token, AppConstants.TOKEN_SECRET_KEY);
        if(result){
            HttpHeaders headers = new HttpHeaders();
            headers.set("x-saas-username", "MyName");
            headers.set("x-saas-eid", "123");
            headers.set("x-saas-uid", "1111111-222222-3333333-444444444");
            ResponseEntity response = new ResponseEntity<>(headers,HttpStatus.OK);
            return response;

        }else{
            HttpHeaders headers = new HttpHeaders();
            headers.set("x-saas-errorcode", "401001");
            headers.set("x-saas-errormessage", "User unauthorized.");
            Map<String,String> body = new HashMap<>();
            body.put("errorCode","401001");
            body.put("errorMessage","User unauthorized.");
            ResponseEntity response = new ResponseEntity<>(body,headers,HttpStatus.UNAUTHORIZED);
            return response;
        }
    }

    private boolean matchesIgnoredPatterns(String requestUri) {
        if (properties.getIgnoredUrls() == null) {
            return false;
        }

        for (String pattern : properties.getIgnoredUrls()) {
            log.debug("Matching ignored pattern:" + pattern);
            if (pathMatcher.match(pattern, requestUri)) {
                log.debug("Path " + requestUri + " matches ignored pattern " + pattern);
                return true;
            }
        }
        return false;
    }
}
